JS 中有哪些方法可以实现继承
ES6
js
class Animate {
constructor() {
this.type = "animate";
}
}
class Cat extends Animate {
constructor() {
super();
this.name = "cat";
}
}
Cat.__proto__ === Animate; //继承属性
Cat.prototype.__proto__ == Animate.prototype; //继承方法
console.log(new Cat());
js
function Animate() {
this.type = 'animate'
}
Animate.prototype.getType = function() { return this.name }
function Cat() {
Animate.call(this)
this.name = 'cat'
}
extends(Cat, Animate);
function extends = (child, parent) {
child.prototype = Object.create(parent);
child.prototype.constructor = child;
}
Cat.prototype.getName = function() { return this.name }
console.log(new Cat())
ES5
- call
只继承属性,父原型方法调不了
js
function Animate() {
this.type = "animate";
}
function Cat() {
this.name = "cat";
Animate.call(this); // Animate.prototype 的原型方法调用不了
}
console.log(new Cat());
- 原型链继承
js
function Animate() {
this.type = "animate";
}
function Cat() {
this.name = "cat";
}
Cat.prototype = new Animate(); // 实例共用 Animate 属性,一改全改
Cat.prototype.constructor = Cat;
console.log(new Cat());
- 组合模式-寄生
js
function Animate() {
this.type = "animate";
}
Animate.prototype.getAnimate = function () {
console.log("getAnimate");
};
function Cat() {
this.name = "cat";
Animate.call(this, name);
}
Cat.prototype = Object.create(Animate.prototype); // 这种 Animate 原型方法会在父级
Cat.prototype.getCat = function () {
console.log("getCat");
};
// Cat.prototype = new Animate() // 会多一个 Animate 属性
// Cat.prototype = Animate.prototype // 这种 Cat.prototype 自己方法需要写到,这一行下面,Animate 原型方法跟 Cat 在同一级
Cat.prototype.constructor = Cat;
console.log(new Cat());
原型链
构造函数有 proto 指向 Function.prototype
js
function Animate() {
this.name = "animate";
}
const cat = new Animate();
cat.__proto__ === Animate.prototype;
Animate.prototype.constructor === Animate;
Object.prototype.__proto__ === null;
Animate.__proto__ === Function.prototype;
function Object(a, b) {
return a + b;
}
var add = new Function("a", "b", "return a+b");
Object.__proto__ = Function.prototype;
Function.__proto__ = Function.prototype;
Function.__proto__ === Object.__proto__;
Object.create
js
function create(prototype) {
function fn() {}
fn.prototype = prototype;
return new fn();
}
ES5 和 ES6 继承区别
- ES6 需要 在子类调用 super 放可获得父类私有属性
- 默认严格模式、不存在变量提升、方法不可以枚举